package models;

import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import play.data.format.Formats;
import play.data.validation.Constraints;
import play.db.ebean.Model;

import com.avaje.ebean.Ebean;
import com.smartsheet.api.models.UserProfile;

/**
 * User entity managed by Ebean
 */
@Entity
@Table(name="ss_user")
public class User extends Model {

    private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue//(strategy=GenerationType.SEQUENCE, generator="ss_token_seq")
    @Column(name="user_id", nullable=false, unique=true)
	public Long userId;
	
    @Constraints.Required
    @Constraints.Email
    @Formats.NonEmpty
    @Column(nullable=false, unique=true)	// unique and non-null constraint to postgresql
    public String email;
    
    public String firstName;
    public String lastName;
    public Long smartsheetId;
    
    @OneToOne(cascade=CascadeType.ALL)
    public SmartsheetToken token;
    
//    @OneToMany(mappedBy="user", cascade=CascadeType.ALL)
//    public List<SignDocument> documents;
    
    /**
     * Update with Smartsheet UserProfile response.
     * 
     * @param profile
     */
    public void updateFromProfile(UserProfile profile) {
		email = profile.getEmail();
		smartsheetId = profile.getId();
		firstName = profile.getFirstName();
		lastName = profile.getLastName();
    }

    public static Model.Finder<Long, User> find = new Finder<Long, User>(Long.class, User.class);
	
    /**
     * Retrieve all users.
     */
    public static List<User> findAll() {
        return find.all();
    }

    /**
     * Retrieve a User by email.
     * 
     * @param email
     * @return
     */
    public static User findByEmail(String email) {
        return find.where().eq("email", email).findUnique();
    }
    
    /**
     * Save if user is new user or update if user is existing user.
     * 
     * @param user
     */
	public static void saveOrUpdate(User user) {
		if (getById(user.userId) != null) {
			// update if already exists
			Ebean.update(user);
		} else {
			// create new one if it does not exist
			Ebean.save(user);
		}
	}

	/**
	 * Get user by userId.
	 * 
	 * @param userId
	 * @return
	 */
	public static User getById(Long userId) {
		if (userId != null) {
			User user = User.find.byId(userId);
			return user;
		}
		return null;
	}
	
	/**
	 * Delete a user by userId
	 * 
	 * @param userId
	 */
	public static void deleteById(Long userId) {
		if (userId != null) {
			User user = User.find.byId(userId);
			if (user != null && user.userId != null) {
				Ebean.delete(user);
			}
		}
	}

}

